using System.Collections.Immutable;
using DimensionsHelper.LanguageService.Symbols;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public class AnalysisInteger : AnalysisExpression
{
    internal AnalysisInteger(IntegerLiteral source, AnalysisNode? parent) :
        base(AnalysisBoundKinds.Literal, source, parent)
    {
        Syntax = source;
        Value = source.Value;
        Bind(ValueTypeSymbol.Long);
    }


    public override IntegerLiteral Syntax { get; }


    /// <summary>
    ///     整数常量数值
    /// </summary>
    public int Value { get; }


    public override AnalysisExpression? WithImplicitlyConversion(ValueTypeSymbol targetType)
    {
        if (targetType == ValueTypeSymbol.Long || targetType == ValueTypeSymbol.Any)
        {
            return this;
        }

        if (targetType == ValueTypeSymbol.Categorical)
        {
            CategoricalLiteral categorical = NodeConverter.ToCategorical(Syntax);
            CategoryLiteral category = NodeFactory.CreateCategoryLiteral(categorical,
                null, null, null, null);
            category.Update(Syntax).UpdateFrom(Syntax);
            categorical.AddCategory(category);
            return AnalysisNodeFactory.Categorical(categorical, Parent);
        }

        if (targetType == ValueTypeSymbol.Double)
        {
            return AnalysisNodeFactory.Double(NodeConverter.ToDouble(Syntax, Value), Parent);
        }

        if (targetType == ValueTypeSymbol.Date &&
            Value >= DateTime.MinValue.ToBinary() &&
            Value <= DateTime.MaxValue.ToBinary())
        {
            return AnalysisNodeFactory.Date(Syntax, DateTime.FromBinary(Value), Parent);
        }

        return targetType == ValueTypeSymbol.Boolean
            ? AnalysisNodeFactory.Boolean(NodeConverter.ToBoolean(Syntax, Value != 0), Parent)
            : null;
    }


    public override IEnumerable<AnalysisNode> GetChildren()
    {
        return ImmutableArray<AnalysisNode>.Empty;
    }

    internal override void AddChild(AnalysisNode child)
    {
        throw new NotSupportedException("AnalysisInteger cannot have children.");
    }
}


public static partial class AnalysisNodeFactory
{
    /// <summary>
    /// 创建一个整数常量
    /// </summary>
    /// <param name="syntaxNode">原始语法节点</param>
    /// <param name="parent">父节点</param>
    public static AnalysisInteger Integer(IntegerLiteral syntaxNode, AnalysisNode? parent)
    {
        return new AnalysisInteger(syntaxNode, parent);
    }
}
